#include "common.h"
#include <codecvt>
#include <iostream>
#include <sys/stat.h>

// String string2wstring(const std::string &str) {
//     using convert_typeX = std::codecvt_utf8<wchar_t>;
//     std::wstring_convert<convert_typeX, wchar_t> converterX;
//     return converterX.from_bytes(str);
// }

Common::Common(void) {
    // 使用构造函数初始化可执行文件的全路径
    if (exePath.empty()) {
        TCHAR buffer[_MAX_PATH];
        ssize_t len = 0;
        if ((len = readlink("/proc/self/exe", buffer, _MAX_PATH - 1)) != -1) {
            buffer[len] = '\0';
            exePath = buffer;
        }
    }
}

Common::~Common(void) {}

Common &Common::getInstance() {
    static Common instance;
    return instance;
}

void Common::showMessageBox(bool error, const String &message) {
    // if (error) {
    //     MessageBox(NULL, message.c_str(), L"错误", MB_OK | MB_ICONERROR);
    // } else {
    //     MessageBox(NULL, message.c_str(), L"提示", MB_OK | MB_ICONINFORMATION);
    // }
    if (error) {
        std::cout << "[error] " << message << std::endl;
    } else {
        std::cout << "[info ] " << message << std::endl;
    }
}

#ifdef DEBUG
void Common::debug(const String &message) { showMessageBox(false, message); }
#else
void Common::debug(const String &message) {}
#endif

bool Common::isFileExists(const String &filename) {
    struct stat buf;
    return (stat(filename.c_str(), &buf) == 0) && (S_ISREG(buf.st_mode) != 0);
}

String Common::getExePath() { return exePath; }

String Common::getExeDir() {
    if (exeDir.empty()) {
        size_t lastSlash = exePath.rfind('/');
        exeDir = exePath.substr(0, lastSlash);
    }
    return exeDir;
}

String Common::getEnvVar(const String &name) {
    String result;
    char *value = ::getenv((TCHAR *)name.c_str());
    if (value != NULL) {
        result = value;
    }
    return result;
}

std::list<String> Common::splitString(const String &text, const TCHAR &delimiter) {
    std::list<String> rtn;
    size_t from = 0;
    size_t pos = text.npos;
    while ((pos = text.find(delimiter, from)) != text.npos) {
        String part = text.substr(from, pos - from);
        if (!part.empty()) {
            rtn.push_back(part);
        }
        from = pos + 1;
    }
    if (from + 1 < text.length()) {
        rtn.push_back(text.substr(from));
    }
    return rtn;
}

String Common::trimString(String &text) {
    size_t start = 0;
    size_t end = text.length();
    while (start != end) {
        wchar_t head = text[start];
        wchar_t rear = text[end - 1];
        if (head == ' ' || head == '\t' || head == '\r' || head == '\n') {
            start++;
        } else if (rear == ' ' || rear == '\t' || rear == '\r' || rear == '\n') {
            end--;
        } else {
            break;
        }
    }
    return text.substr(start, end - start);
}

const String Common::wstring2utf8(const std::wstring &text) {
    std::wstring_convert<std::codecvt_utf8<wchar_t>> cvt;
    return cvt.to_bytes(text);
}

void Common::setCommandLineArgs(const std::list<String> &args) { commandLineArgs = args; }

std::list<String> Common::getCommandLineArgs() { return commandLineArgs; }
